#include "PluginMgr.h"
#include "iPlugin.h"
#include <wx/dynlib.h>
#include <wx/log.h>
#include <wx/wx.h>
#include <wx/xml/xml.h>
#include <wx/filename.h>


wxString PluginHouse::toString(){
	wxString ret;
	ret += wxT("Plugin: ")+plugin_name + wxT(":\n");
	ret += wxT("\tfile_name: ")+file_name + wxT("\n");
	ret += wxT("\tfile_path: ")+file_path+ wxT("\n");
	ret += wxT("\ttree_uid: ")+tree_uid+ wxT("\n");
	ret += wxT("\ttree_path: ")+tree_path + wxT("\n");
	ret += wxT("\ttree_name: ")+tree_name + wxT("\n");
	ret += wxT("\ticon_file: ")+icon_file+ wxT("\n");
	ret += wxT("\thas_display_tab_gui: ");

	if(has_display_tab_gui){
	   	ret += wxT("true");
	}else{
		ret += wxT("false");
	}
	ret+= wxT("\n");
	return ret ;
}


PluginMgr::PluginMgr(void){
	wxLogDebug("Plugin Manager Instantiated\n");
}

void PluginMgr::saveConfig(void){
	wxDynamicLibrary dll;
//@TODO Add lame crap to make this work with M$ Windoze
	wxString name;
	wxString dir = wxGetCwd()+_("/");
	wxFileName filePath;
	filePath.Assign(wxFindFirstFile(dir+_("*.so")));
	//while( !filePath.empty() ){
	while( filePath.IsOk() ){
	//wxFileName::SplitPath((const wxString&) filePath, fullpath, path, name, ext, NULL, NULL);
	name = filePath.GetName();
	name = name.Right(name.Length()-3);
	dll.Load(wxGetCwd()+_("/")+wxDynamicLibrary::CanonicalizeName(name));
	if(dll.IsLoaded()){

		//Create a valid function pointer using the function pointer type in plugin.h
		wxDYNLIB_FUNCTION(CreatePlugin_function,CreatePlugin,dll);
		//check if the function is found
		if(pfnCreatePlugin){
			//Important: Use Detach(), otherwise the DLL will be unloaded once
			//the wxDynamibLibrary object goes out of scope
			//dll.Detach(); //want the plugin to unload when we are done here
			//Create the plugin
			Plugin* plugin = pfnCreatePlugin();

			wxXmlNode *root=new wxXmlNode(wxXML_ELEMENT_NODE,wxT("Plugins"));
			configuration.SetRoot(root);

			wxXmlNode *pluginNode =new wxXmlNode (wxXML_ELEMENT_NODE,wxT("Plugin"));
			pluginNode->AddProperty(wxT("Name"),plugin->getPluginName());
			root->AddChild(pluginNode);

			wxXmlNode *pluginFile=new wxXmlNode (wxXML_ELEMENT_NODE,wxT("File"));
			pluginFile->AddProperty(wxT("Name"), filePath.GetFullName());
			pluginFile->AddProperty(wxT("Path"),dir);
			pluginNode->AddChild(pluginFile);

			wxXmlNode *tree=new wxXmlNode (wxXML_ELEMENT_NODE,wxT("Tree"));
			tree->AddProperty(wxT("UID"),plugin->getTreeUID());
			tree->AddProperty(wxT("TreePath"),plugin->getTreePath());
			tree->AddProperty(wxT("TreeName"),plugin->getTreeName());
			pluginNode->AddChild(tree);

			wxXmlNode *icon=new wxXmlNode (wxXML_ELEMENT_NODE,wxT("Icon"));
			icon->AddProperty(wxT("ImageFileName"),plugin->getIconFileName());
			pluginNode->AddChild(icon);

			wxXmlNode *displayTabGUI=new wxXmlNode (wxXML_ELEMENT_NODE,wxT("DisplayTabGUI"));
			if(plugin->hasDisplayTabGUI()){
				displayTabGUI->AddProperty(wxT("Has"),wxT("true"));
			}else{
				displayTabGUI->AddProperty(wxT("Has"),wxT("false"));
			}
			pluginNode->AddChild(displayTabGUI);

		}//pg
	}//pg
    filePath = wxFindNextFile();
}//while filePath not empty
	if (!configuration.Save (wxT("plugin_config.xml"), 2))
	{
		wxLogWarning(wxT("WTF! Failed to save plugin config file: %s"),"plugin_config.xml");
	}
}


PluginHouse PluginMgr::first(void){
	phit = ph.begin();
	max = ph.size();
	cnt = 1;
	return phit->second;
}

PluginHouse PluginMgr::next(void){
	if(cnt<max){
	   	++phit;
	}else{
		phit = ph.begin();
	}
	cnt++;
	return phit->second;
}

bool PluginMgr::end(void){
	return (cnt <= max ) ? false : true;
}

bool PluginMgr::loadConfig(void){
	if (!configuration.Load(wxT("plugin_config.xml")))
		return false;
	// start processing the XML file
	if (configuration.GetRoot()->GetName() != wxT("Plugins"))
		return false;
	wxXmlNode *child = configuration.GetRoot()->GetChildren();
	while (child) {
		if (child->GetName() == wxT("Plugin")) {
			wxString content = child->GetNodeContent();
			wxString plugin_name = child->GetPropVal(wxT("Name"), wxT("MoFo"));
			ph[plugin_name].plugin_name = plugin_name;
			wxXmlNode *grandChild = child->GetChildren();
			while (grandChild) {
					wxString gcName = grandChild->GetName();
				if (gcName == wxT("File")) {
					ph[plugin_name].file_name = grandChild->GetPropVal(wxT("Name"), wxT("MoFo"));
					ph[plugin_name].file_path = grandChild->GetPropVal(wxT("Path"), wxT("MoFo"));
				}else if(gcName == wxT("Tree")){
					ph[plugin_name].tree_uid = grandChild->GetPropVal(wxT("UID"), wxT("MoFo"));
					ph[plugin_name].tree_path = grandChild->GetPropVal(wxT("TreePath"), wxT("MoFo"));
					ph[plugin_name].tree_name = grandChild->GetPropVal(wxT("TreeName"), wxT("MoFo"));
				}else if(gcName == wxT("Icon")){
					ph[plugin_name].icon_file = 
						grandChild->GetPropVal(wxT("ImageFileName"), wxT("MoFo"));
				}else if(gcName == wxT("DisplayTabGUI")){
					ph[plugin_name].has_display_tab_gui= 
						(grandChild->GetPropVal(wxT("Has"), 
												wxT("false")) == wxT("true")) ? true:false;
				}
				grandChild = grandChild->GetNext();
			}
				wxMessageBox(ph[plugin_name].toString());
		}
		child = child->GetNext();
	}
	return true;
}
